#include "drv_btn.h"

#define LIST_CNT(a) (sizeof(a) / sizeof(a[0])) 

uint8_t drvQueryIo(uint8_t num);
void printRet(uint8_t num);

DRV_BTN_S DrvBtnList[] = {
	{0, DRV_BTN_STATE_IDLE, 5, 5, 0, 0, 0, 500, drvQueryIo, printRet},
};

void drvBtnScan(void)
{
	uint8_t btnlevel = 0;
	DRV_BTN_RET_S ret = {0, 0};
	for(uint8_t i = 0;i < LIST_CNT(DrvBtnList);i++) {
		btnlevel = DrvBtnList[i].querystate(i);
		switch(DrvBtnList[i].state) {
			case DRV_BTN_STATE_IDLE:
				if(btnlevel) {
					DrvBtnList[i].state = DRV_BTN_STATE_PRESS_CHECK;
				}
				break;
			case DRV_BTN_STATE_IDLE_CHECK:
				DrvBtnList[i].idlecnt++;
				if(DrvBtnList[i].idlecnt > DRV_CLICK_LIMIT) {
					DrvBtnList[i].idlecnt = 0;
					DrvBtnList[i].clickcnt = 0;
					DrvBtnList[i].presstime = 0;
					DrvBtnList[i].state = DRV_BTN_STATE_IDLE;
				}
				if(btnlevel) {
					DrvBtnList[i].filtercnt = 0;
					DrvBtnList[i].state = DRV_BTN_STATE_PRESS_CHECK;
				}
				break;
			case DRV_BTN_STATE_PRESS_CHECK:
				if(btnlevel) {
					DrvBtnList[i].filtercnt++;
					if(DrvBtnList[i].filtercnt > DrvBtnList[i].pressfilter) {
						DrvBtnList[i].state = DRV_BTN_STATE_PRESSED;
						DrvBtnList[i].filtercnt = 0;						
					}
				} else {
					DrvBtnList[i].state = DRV_BTN_STATE_IDLE_CHECK;
					DrvBtnList[i].filtercnt = 0;
				}
				break;
			case DRV_BTN_STATE_PRESSED:
				if(btnlevel) {
					DrvBtnList[i].presstime++;
					if(DrvBtnList[i].presstime > DrvBtnList[i].maxpresstime) {
						ret.ret = DRV_BTN_RET_PRESS;
						ret.cnt = 0;
						DrvBtnList[i].retcallback(i, ret);
						memset(&ret, 0, sizeof(DRV_BTN_RET_S));
						DrvBtnList[i].state = DRV_BTN_STATE_EXCEED;
					}
				} else {
					DrvBtnList[i].clickcnt++;
					DrvBtnList[i].state = DRV_BTN_STATE_POP_CHECK;
				}
				break;
			case DRV_BTN_STATE_POP_CHECK:
				if(btnlevel == 0) {
					DrvBtnList[i].filtercnt++;
					if(DrvBtnList[i].filtercnt > DrvBtnList[i].popfilter) {
						DrvBtnList[i].state = DRV_BTN_STATE_IDLE_CHECK;
						DrvBtnList[i].filtercnt = 0;
						DrvBtnList[i].idlecnt = 0;
						ret.ret = DRV_BTN_RET_CLICK;
						ret.cnt = DrvBtnList[i].clickcnt;
						DrvBtnList[i].retcallback(i, ret);
					}
				} else {
					if(DrvBtnList[i].presstime > DrvBtnList[i].maxpresstime)
						DrvBtnList[i].state = DRV_BTN_STATE_EXCEED;
					else
						DrvBtnList[i].state = DRV_BTN_STATE_PRESSED;
					DrvBtnList[i].filtercnt = 0;
				}
				break;
			case DRV_BTN_STATE_EXCEED:
				if(btnlevel == 0) {
					DrvBtnList[i].state = DRV_BTN_STATE_POP_CHECK;
				}
				break;
			default:
				break;
		}
	}
}